#!/usr/bin/env python
# encoding: utf-8
"""
util.py

This file contains utility functions including:
1. Files I/O
2. Sequence Operations

Created by Yuzong Liu on 2011-03-06.
Copyright (c) 2011 . All rights reserved.
"""

import sys
import os
import re
import string
import copy

def readMISFile(filename,MIS,SDC):
	pattern1 = re.compile("MIS\(([0-9]+)\) = ([^\r\n]*)")	
	pattern2 = re.compile("SDC = (.*)")
	inputFile = open(filename,'r')
	currentLine = inputFile.readline()
	print("Reading MIS parameters ...")
	while currentLine != '':
		currentLine = currentLine.strip()
		if len(currentLine) > 0:
			misPattern = pattern1.search(currentLine)
			sdcPattern = pattern2.search(currentLine)
			if misPattern != None:
				MIS[int(misPattern.group(1))] = float(misPattern.group(2))
			if sdcPattern != None:
				SDC = float(sdcPattern.group(1))
		currentLine = inputFile.readline()

	
	return MIS,SDC


def readDataFile(filename,SequenceDataset):
	pattern = re.compile("({.+?})+?")
	inputFile = open(filename,'r')
	currentLine = inputFile.readline()
	while currentLine != '':
		currentLine = currentLine.strip()
		sequence = []
		if len(currentLine) > 0:
			matchPattern = pattern.findall(currentLine)
			for itemset in matchPattern:
				# print itemset
				tmp = []
				for item in re.split(',',itemset[1:len(itemset)-1]):
					# print item
					tmp.append(int(item))
					# print tmp
				# print tmp
				sequence.append(tmp)
			SequenceDataset.append(sequence)
		currentLine = inputFile.readline()	
	return SequenceDataset	
				

def sort(MIS):
#	print("Sorting MIS parameters ...")
	sortedIdx = sorted(MIS,key=lambda x: MIS[x])
	return sortedIdx

	
	
def lenSequence(element):
	c = 0
	for item in element:
		c += len(item)
	return c


	
# def isItemInElement(query,element):
#   c = 0
#   for item in element:
#       c += item.count(query) 
#   return c    

def isItemInElement(query,element):
	flag = False
	pos = 0
	idx = 0
	for item in element:
	    if item.count(query) > 0:
	        idx = item.index(query)
	        return True, [pos,idx]
	    pos += 1    
	return flag, [pos,idx]

def isItemInSequence(query,sequence):
	for element in sequence:
		for item in element:
			if item == query:
				return True
			else:
				continue
	return False
	
def countItem(query,element):
    c = 0
    for item in element:
        c += item.count(query)
	return c	
	
def isContained(query,element):
	"returns true if query is contained in the element"
	len_Query = len(query) # same as the r on Page 38 in the textbook
	len_Element = len(element) # same as the v
	i = 0
	j = 0
	if len_Element < len_Query:
		return False
	while i < len_Query and j < len_Element:
		if len(element[j]) < len(query[i]): 
			# no chance finding match in element[j]
			j += 1
			continue
		else:
			flag = True
			if (set(query[i])<=set(element[j])):
				# find subsequence
				i += 1
				j += 1
			else:
				j += 1		
	if i < len_Query:
		return False,-1,-1
	else:
		pos = j - 1
		idx = element[pos].index(query[-1][-1])	
		return True,pos,idx
	
def isEqual(s1,s2):
	if lenSequence(s1) != lenSequence(s2):
		return False
	else:
		for i in range(0,len(s1)):
			if s1[i]==s2[i]:
				continue
			else:
				return False
		return True
#		return getAllItems(s1) == getAllItems(s2)
	
def isSequenceFrequent(sequence, F):
	for dataSeq in F:
		Fsequence = dataSeq.itemset
		if Fsequence==sequence:
			return 1
		else:
			continue
	return 0	

def findMIS(sequence, MIS):
	minMIS = MIS(sequence[0])
	for item in sequence:
		if MIS[item] < minMIS:
			minMIS=MIS[item]
		else:
			continue
	return minMIS
		
def reshapeSequence(sequence):
	for element in sequence:
		if element == []:
			sequence.remove(element)
		else:
			continue
	return sequence
	
def getAllItems(s):
	items = []
	for item in s:
		for i in range(0,len(item)):
			items.append(item[i])
	return items

def removej(S,i,L,SDC,n):
	sind = 0
	flagjump=0
	while sind < len(S):
		eind = 0
		while eind < len(S[sind]):
			iind = 0
			while iind < len(S[sind][eind]):
				item = S[sind][eind][iind]
				if abs(float(L[item])/n - float(L[i])/n) > SDC:
					if len(S[sind])==1 and len(S[sind][eind])==1:
						flagjump =1
						del S[sind]
						sind -= 1
						break						
					elif len(S[sind][eind])==1:
						del S[sind][eind]
						eind -= 1
						break
					else:
						del S[sind][eind][iind]
						iind -= 1
				iind += 1
			if flagjump ==1:
				flagjump=0
				break
			eind +=1
		sind +=1
	return S

def removei(S,i):
	sind = 0
	flagjump = 0
	while sind < len(S):
		eind = 0
		while eind < len(S[sind]):
			iind = 0
			while iind < len(S[sind][eind]):
				item = S[sind][eind][iind]
				if item == i:
					if len(S[sind])==1 and len(S[sind][eind])==1:
						flagjump =1
						del S[sind]
						sind -= 1
						break
					elif len(S[sind][eind])==1:
						del S[sind][eind]
						eind -= 1
						break
					else:
						del S[sind][eind][iind]
						iind -=1
				iind += 1
			if flagjump:
				flagjump=0
				break
			eind +=1
		sind +=1
	return S

def formatStr(seq):
	fseq = '<'	
	for elem in seq:
		fseq = fseq+'{'
		cnt = 0
		for item in elem:
			if cnt == 0:
				fseq = fseq+str(item)+','
			else:
				fseq = fseq+' '+str(item)+','
			cnt = cnt + 1
		fseq = fseq[0:-1] +'}'
	fseq = fseq+'>'					 
	return fseq